package com.destin.basic.service.admin.impl;

import com.baomidou.mybatisplus.plugins.pagination.PageHelper;
import com.destin.basic.config.RedisUtils;
import com.destin.basic.constans.RedisKey;
import com.destin.basic.dao.UserMapper;
import com.destin.basic.dto.UserModifyDTO;
import com.destin.basic.eneity.User;
import com.destin.basic.exception.BusinessException;
import com.destin.basic.security.AdminUserDetails;
import com.destin.basic.security.LoginUserInfo;
import com.destin.basic.service.admin.AdminService;
import com.destin.basic.util.CloneUtil;
import com.destin.basic.util.JwtTokenUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;
import java.util.Objects;

/**
 * @author: Destin
 * @date: 2022-02-24
 */
@Slf4j
@Service
public class AdminServiceImpl implements AdminService {

    @Resource
    private JwtTokenUtils jwtTokenUtils;
    @Resource
    private RedisUtils redisUtils;
    @Resource
    private PasswordEncoder passwordEncoder;
    @Resource
    private UserMapper userMapper;

    @Override
    public User getAdminByUsername(String username) {
        User user = new User();
        user.setUsername(username);
        User userEntity = userMapper.selectOne(user);
        if (Objects.isNull(userEntity))
            throw BusinessException.create("查无此用户！");
        return userMapper.selectOne(user);
    }
    @Override
    public String login(String username, String password) {
        String token = null;
        // 密码需要客户端加密后传递
        try {
            User user = new User();
            user.setUsername(username);
            user = userMapper.selectOne(user);
            UserDetails userDetails = loadUserByUsername(username);
            if(!passwordEncoder.matches(password,userDetails.getPassword()))
                throw new BadCredentialsException("密码不正确");
            UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
            SecurityContextHolder.getContext().setAuthentication(authentication);
            token = jwtTokenUtils.createToken(username, user.getId(), false);
            // 用户信息放入redis
            putUserToCache(user);
        } catch (AuthenticationException e) {
            log.error("登录异常:{}", e.getMessage());
        }
        return token;
    }

    @Override
    public List<User> selectList() {
        PageHelper.startPage(1,10);
        return userMapper.selectPageByParam(null);
    }

    @Override
    public Boolean add(UserModifyDTO userModifyDTO) {
        User user = CloneUtil.clone(userModifyDTO, User.class);
        user.setPassword(passwordEncoder.encode(userModifyDTO.getPassword()));
        return userMapper.insert(user) > 0;
    }

    private void putUserToCache(User user) {
        LoginUserInfo clone = CloneUtil.clone(userMapper.selectOne(user), LoginUserInfo.class);
        redisUtils.set(RedisKey.getLoginUserKey(user.getUsername()), clone);
    }

    public UserDetails loadUserByUsername(String username){
        //获取用户信息
        User user = getAdminByUsername(username);
        if (user != null) {
            // 查询权限，进行封装
//            List<UmsPermission> permissionList = getPermissionList(admin.getId());
            return new AdminUserDetails(user);
        }
        throw new UsernameNotFoundException("用户名或密码错误");
    }

}
